package pers.schieber.crud.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import pers.schieber.crud.bean.Employee;
import pers.schieber.crud.bean.Message;
import pers.schieber.crud.service.EmployeeService;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @PackageName: pers.schieber.crud.controller
 * @ClassName: EmployeeController
 * @Description: 员工CRUD页面表现层
 * @Author: Schieber
 * @Date: 2021/4/10 下午 19:34
 */
@Controller
public class EmployeeController {

    @Resource
    private EmployeeService employeeService;


    /**
     * 添加员工(支持JSR303校验)
     *
     * @param employee 添加员工的对象
     * @return 返回添加操作后数据库返回的自定义Message信息及影响行数
     */
    @ResponseBody
    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public Message addEmployee(@Valid Employee employee, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 校验失败后返回结果及错误信息
            Map<String, Object> map = new HashMap<>(16);
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors
            ) {
                System.out.println("错误的字段名：" + fieldError.getField());
                System.out.println("默认错误信息：" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            return Message.fail().add("errorFields", map);
        } else {
            int affect = employeeService.addEmployee(employee);
            return Message.success().add("affect", affect);
        }
    }


    /**
     * 通过id单独或批量删除员工
     *
     * @param employeesId 需要删除的员工/员工们的id
     * @return 返回删除操作后数据库的影响行数
     */
    @ResponseBody
    @RequestMapping(value = "/delete/{employeesId}", method = RequestMethod.DELETE)
    public Message deleteEmployee(@PathVariable(value = "employeesId") String employeesId) {
        String separator = "-";
        // 批量删除员工
        if (employeesId.contains(separator)) {
            List<Integer> employeesIdList = new ArrayList<>();
            String[] splits = employeesId.split(separator);
            for (String employeeId : splits) {
                employeesIdList.add(Integer.parseInt(employeeId));
            }
            int affect = employeeService.batchDeleteEmployees(employeesIdList);
            return Message.success().add("affect", affect);
        } else {
            // 单独删除员工
            Integer employeeId = Integer.parseInt(employeesId);
            int affect = employeeService.deleteEmployee(employeeId);
            return Message.success().add("affect", affect);
        }
    }

    /**
     * 根据主键id修改员工
     *
     * @param employee 修改员工的对象
     * @return 返回修改员工后的影响行数
     */
    @ResponseBody
    @RequestMapping(value = "/updateEmployee/{empId}", method = RequestMethod.PUT)
    public Message updateEmployee(Employee employee) {
        employeeService.updateEmployee(employee);
        return Message.success();
    }

    /**
     * 查询所有员工
     *
     * @param pageNum 传入的当前页码，如果没有进行传入，默认传入第一页
     * @param model   用于保存数据的模型
     * @return 返回添加操作后数据库返回的自定义Message信息及分页数据
     */
    @ResponseBody
    @RequestMapping(value = "/employees")
    public Message findAllEmployees(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, Model model) {
        // 在查询之前调用，传入页码以及每页显示数量
        PageHelper.startPage(pageNum, 5);
        // 紧跟在startPage方法后面的查询就是分页查询
        List<Employee> employeeList = employeeService.findAllEmployees();
        // 使用pageInfo包装查询后的结果，并传入页码导航页显示的页数，然后将pageInfo返回给页面
        // pageInfo中封装了详细的分页信息，包括查出的列表数据
        PageInfo pageInfo = new PageInfo(employeeList, 5);
        // 将信息保存在Model中
        model.addAttribute("pageInfo", pageInfo);
        // 返回视图页面
        return Message.success().add("pageInfo", pageInfo);
    }

    /**
     * 校验员工姓名是否重复与可用
     *
     * @param empName 传入员工姓名
     * @return 返回添加操作后数据库返回的自定义Message成功或失败的信息
     */
    @ResponseBody
    @RequestMapping(value = "/checkEmpName", method = RequestMethod.GET)
    public Message checkEmpName(@RequestParam(value = "empName") String empName) {
        // 先判断用户名是否合法的正则表达式
        String empNameRegExp = "(^[a-zA-Z][a-zA-Z0-9_]{4,14}$)|(^[\\u4e00-\\u9fa5_a-zA-Z0-9_]{2,5}$)";
        if (!empName.matches(empNameRegExp)) {
            return Message.fail().add("hintMessage", "员工姓名应在【英文5-15位，中文2-5位】区间内！");
        }

        // 数据库验证用户名是否重复
        boolean enabled = employeeService.checkEmpName(empName);
        if (enabled) {
            return Message.success();
        } else {
            return Message.fail().add("hintMessage", "员工姓名已存在！");
        }
    }

    /**
     * 通过主键id查询员工信息
     *
     * @param id 员工id
     * @return 返回根据主键id查询出的员工对象
     * @PathVariable 从一个URI模板里取出参数来填充数据
     */
    @ResponseBody
    @RequestMapping(value = "/findEmployeeById/{id}", method = RequestMethod.GET)
    public Message findEmployeeById(@PathVariable(value = "id") Integer id) {
        Employee employee = employeeService.findEmployeeById(id);
        return Message.success().add("employee", employee);
    }

}
